using System;
using System.Diagnostics;
using DeviceCommons;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace DeviceDataGenerator
{
    /// <summary>
    /// AES模式配置演示程序
    /// </summary>
    public class AesModeConfigurationDemo
    {
        public static void RunDemo()
        {
            Console.WriteLine("=== DeviceCommonsOptions AES模式配置演示 ===\n");

            Console.WriteLine("🔧 AES加密模式说明:");
            Console.WriteLine("- 快速模式 (Fast): 1000次PBKDF2迭代，启用密钥缓存，适用于性能测试");
            Console.WriteLine("- 安全模式 (Secure): 60000次PBKDF2迭代，禁用缓存，适用于生产环境\n");

            // 演示1：默认AES加密（使用快速模式保持向后兼容）
            Console.WriteLine("📋 演示1：默认AES加密（快速模式）");
            DemonstrateConfiguration("默认配置", services =>
            {
                services.AddDeviceCommons()
                       .WithDefaultAesEncryption("test-password-123");
            });

            // 演示2：显式配置快速模式
            Console.WriteLine("\n📋 演示2：显式配置快速模式");
            DemonstrateConfiguration("快速模式", services =>
            {
                services.AddDeviceCommons()
                       .WithFastAesEncryption("test-password-123");
            });

            // 演示3：显式配置安全模式
            Console.WriteLine("\n📋 演示3：显式配置安全模式");
            DemonstrateConfiguration("安全模式", services =>
            {
                services.AddDeviceCommons()
                       .WithSecureAesEncryption("test-password-123");
            });

            // 演示4：使用重载方法指定模式
            Console.WriteLine("\n📋 演示4：使用重载方法指定模式");
            DemonstrateConfiguration("指定安全模式", services =>
            {
                services.AddDeviceCommons()
                       .WithDefaultAesEncryption("test-password-123", AesMode.Secure);
            });

            // 性能对比测试
            Console.WriteLine("\n🏃‍♂️ 性能对比测试:");
            PerformanceComparison();

            Console.WriteLine("\n✨ AES模式配置功能已成功集成到DeviceCommonsOptions中！");
        }

        private static void DemonstrateConfiguration(string configName, Action<IServiceCollection> configureServices)
        {
            var services = new ServiceCollection();
            configureServices(services);

            var serviceProvider = services.BuildServiceProvider();
            var options = serviceProvider.GetRequiredService<IOptions<DeviceCommonsOptions>>().Value;
            var configService = serviceProvider.GetRequiredService<IDeviceCommonsConfigurationService>();

            Console.WriteLine($"  配置名称: {configName}");
            Console.WriteLine($"  启用AES加密: {options.EnableDefaultAesEncryption}");
            Console.WriteLine($"  AES模式: {options.AesEncryptionMode} ({GetModeDescription(options.AesEncryptionMode)})");
            Console.WriteLine($"  默认密码: {options.DefaultEncryptionPassword}");
            Console.WriteLine($"  加密函数可用: {configService.EncryptFunc != null}");
            Console.WriteLine($"  解密函数可用: {configService.DecryptFunc != null}");

            // 测试加密解密功能
            if (configService.EncryptFunc != null && configService.DecryptFunc != null)
            {
                var testText = "配置测试数据";
                var encrypted = configService.EncryptFunc(testText);
                var decrypted = configService.DecryptFunc(encrypted);
                Console.WriteLine($"  加密解密测试: {(testText == decrypted ? "✅ 成功" : "❌ 失败")}");
            }
        }

        private static string GetModeDescription(AesMode mode)
        {
            return mode switch
            {
                AesMode.Fast => "快速模式，1000次迭代",
                AesMode.Secure => "安全模式，60000次迭代",
                _ => "未知模式"
            };
        }

        private static void PerformanceComparison()
        {
            var testData = "AES模式性能测试数据，包含一些中文字符以测试编码处理";
            var testPassword = "performance-test-password";
            const int iterations = 50;

            Console.WriteLine("┌──────────┬──────────────┬──────────────┬──────────────┐");
            Console.WriteLine("│   模式   │  平均加密时间  │  平均解密时间  │    总时间    │");
            Console.WriteLine("├──────────┼──────────────┼──────────────┼──────────────┤");

            // 测试快速模式
            var (fastEncryptTime, fastDecryptTime, fastTotalTime) = MeasurePerformance(
                AesMode.Fast, testData, testPassword, iterations);

            Console.WriteLine($"│ 快速模式 │{fastEncryptTime,11:F3} ms │{fastDecryptTime,11:F3} ms │{fastTotalTime,11:F3} ms │");

            // 测试安全模式
            var (secureEncryptTime, secureDecryptTime, secureTotalTime) = MeasurePerformance(
                AesMode.Secure, testData, testPassword, iterations);

            Console.WriteLine($"│ 安全模式 │{secureEncryptTime,11:F3} ms │{secureDecryptTime,11:F3} ms │{secureTotalTime,11:F3} ms │");

            // 计算性能差异
            var encryptSpeedup = secureEncryptTime / fastEncryptTime;
            var decryptSpeedup = secureDecryptTime / fastDecryptTime;
            var totalSpeedup = secureTotalTime / fastTotalTime;

            Console.WriteLine("├──────────┼──────────────┼──────────────┼──────────────┤");
            Console.WriteLine($"│ 性能提升 │{encryptSpeedup,11:F1}x     │{decryptSpeedup,11:F1}x     │{totalSpeedup,11:F1}x     │");
            Console.WriteLine("└──────────┴──────────────┴──────────────┴──────────────┘");

            Console.WriteLine($"\n💡 性能分析:");
            Console.WriteLine($"   - 快速模式比安全模式快约 {totalSpeedup:F1} 倍");
            Console.WriteLine($"   - 快速模式适用于性能测试和开发环境");
            Console.WriteLine($"   - 安全模式适用于生产环境，提供更高的安全性");
        }

        private static (double encryptTime, double decryptTime, double totalTime) MeasurePerformance(
            AesMode mode, string testData, string password, int iterations)
        {
            var services = new ServiceCollection();
            services.AddDeviceCommons()
                   .WithDefaultAesEncryption(password, mode);

            var serviceProvider = services.BuildServiceProvider();
            var configService = serviceProvider.GetRequiredService<IDeviceCommonsConfigurationService>();

            var encryptFunc = configService.EncryptFunc!;
            var decryptFunc = configService.DecryptFunc!;

            var sw = Stopwatch.StartNew();

            // 测量加密时间
            sw.Restart();
            string? encrypted = null;
            for (int i = 0; i < iterations; i++)
            {
                encrypted = encryptFunc(testData);
            }
            var encryptTime = sw.ElapsedMilliseconds / (double)iterations;

            // 测量解密时间
            sw.Restart();
            for (int i = 0; i < iterations; i++)
            {
                decryptFunc(encrypted!);
            }
            var decryptTime = sw.ElapsedMilliseconds / (double)iterations;

            var totalTime = encryptTime + decryptTime;

            return (encryptTime, decryptTime, totalTime);
        }
    }
}